﻿using System;
using System.Collections.Generic;
using System.Text;
using llAma.Backend.Interface;
using System.Net;

namespace llamaServer
{
    public partial class Connection : IConnection
    {
        string IConnection.Agent
        {
            get
            {
                return mUserAgent;
            }
        }
        Dictionary<string, IChannel> mChannels = new Dictionary<string, IChannel>();
        bool IConnection.AddChannel(IChannel channel)
        {
            lock (mChannels)
            {
                if (mChannels.ContainsKey(channel.Namespace.ToLower()))
                    return false;
                mChannels[channel.Namespace.ToLower()] = channel;
                return true;
            }
        }

        bool IConnection.RemoveChannel(IChannel channel)
        {
            lock (mChannels)
            {
                if (mChannels.ContainsKey(channel.Namespace.ToLower()))
                {
                    mChannels.Remove(channel.Namespace.ToLower());
                    return true;
                }
                else
                    return false;
            }
        }

        IChannel IConnection.LookupChannel(string fullns)
        {
            lock (mChannels)
            {
                if (!mChannels.ContainsKey(fullns.ToLower()))
                    return null;
                else
                    return mChannels[fullns.ToLower()];
            }
        }

        void IConnection.Send(string data)
        {
            this.SendRaw(data);
        }

        Guid IConnection.UUID
        {
            get { return this.id; }
        }

        string IConnection.Username
        {
            get { return this.mCurrentUser.getInfo("username"); }
        }


        void IConnection.Drop(string reason)
        {
            this.Disconnect(reason);
        }

        bool IConnection.CompatiblityMode
        {
            get { return mCompatibilityMode; }
        }
        DateTime mLoginTime = DateTime.MinValue;
        IUserData IConnection.CurrentUser
        {
            get { return mCurrentUser; }
            set
            {
                if (value == null) throw new InvalidOperationException("CurrentUser cannot be set to null!");
                if (value != null)
                    mLoginTime = DateTime.Now;
                
                mCurrentUser = value;
            }
        }

        void IHandlePackets.HandlePacket(dAmn.Packet p, IConnection sender)
        {
            throw new NotImplementedException();
        }


        System.Net.IPAddress IConnection.RemoteAddress
        {
            get { return ((IConnection)this).RemoteEndPoint.Address; }
        }

        System.Net.IPAddress IConnection.LocalAddress
        {
            get { return ((IConnection)this).LocalEndPoint.Address; }
        }
        IPEndPoint mRemoteEP;
        IPEndPoint mLocalEP;
        System.Net.IPEndPoint IConnection.RemoteEndPoint
        {
            get { return mRemoteEP; }
        }

        System.Net.IPEndPoint IConnection.LocalEndPoint
        {
            get { return mLocalEP; }
        }

        int IConnection.RemotePort
        {
            get { return ((IConnection)this).RemoteEndPoint.Port; }
        }

        int IConnection.LocalPort
        {
            get { return ((IConnection)this).LocalEndPoint.Port; }
        }

        bool IConnection.Connected
        {
            get { return this.Connected; }
        }

        EventHandler<ClientEventArgs> mOnDisconnect = null;
        event EventHandler<ClientEventArgs> IConnection.OnDisconnect
        {
            add
            {
                if (mOnDisconnect == null) mOnDisconnect = value;
                else mOnDisconnect += value;
            }
            remove { if (mOnDisconnect != null) mOnDisconnect -= value; }
        }


        ConnectionState IConnection.State
        {
            get
            {
                return this.State;
            }
            set
            {
                this.State = value;
            }
        }

        DateTime IConnection.LoggedIn
        {
            get { return mLoginTime; }
        }

        DateTime IConnection.LastPacket
        {
            get { return mLastNonIdlePacket; }
        }


        public IChannel[] AllChannels
        {
            get {
                IChannel[] ret;
                lock (mChannels)
                {
                    ret = new IChannel[mChannels.Values.Count];
                    mChannels.Values.CopyTo(ret, 0);
                }
                return ret;
            }
        }
    }
}
